
/**
 *  做一个简单的事件传递机制
 */

export class DocumentEventCenter{

    private static mouseDownMap:Function[];
    private static mouseUpMap:Function[];
    private static mouseMoveMap:Function[];
    private static keyDownMap:Function[];
    private static keyUpMap:Function[];

    static updateRenderFlag:string = "updateRenderFlag";
    static keyDown:string = "keyDown";
    
    static __init__()
    {
        let target = document;
        target.onmousedown = (ev:MouseEvent)=>{
            this.triggerEvent(DocumentEventType.MOUSE_DOWN, ev);
        }
        target.onmouseup = (ev:MouseEvent)=>{
            this.triggerEvent(DocumentEventType.MOUSE_UP, ev);
        }
        target.onmousemove = (ev:MouseEvent)=>{
            this.triggerEvent(DocumentEventType.MOUSE_MOVE, ev);
        }
        target.onkeydown = (ev:KeyboardEvent)=>{
            this.triggerEvent(DocumentEventType.KEY_DOWN, ev);
        }
        target.onkeyup = (ev:KeyboardEvent)=>{
            this.triggerEvent(DocumentEventType.KEY_UP, ev);
        }

    }

    static triggerEvent(eventName:DocumentEventType, evt:any){
        
        let eventFuncList:Function[];
        switch (eventName) {
            case DocumentEventType.KEY_DOWN:
                eventFuncList = this.keyDownMap;
                break;
            case DocumentEventType.KEY_UP:
                eventFuncList = this.keyUpMap;
                break;
            case DocumentEventType.MOUSE_DOWN:
                eventFuncList = this.mouseDownMap;
                break;
            case DocumentEventType.MOUSE_UP:
                eventFuncList = this.mouseUpMap;
                break;
            case DocumentEventType.MOUSE_MOVE:
                eventFuncList = this.mouseMoveMap;
                break;
        
            default:
                break;
        }
        if(eventFuncList && eventFuncList.length){
            eventFuncList.forEach(func=>{
                func(evt);
            })
        }
    }

    private static _eventMap:any = {};
    static regEvent(event:string, caller:any, func:Function, args?:any[]){
        let arr = this._eventMap[event] ||= [];
        if(args){

            arr.push(func.bind(caller, ...args));
        }else{

            arr.push(func.bind(caller));
        }
    }

    static sendEvent(event:string, args?:any[]){
        let arr = this._eventMap[event];
        if(arr && arr.length){
            for (let index = 0; index < arr.length; index++) {
                const evFunc:Function = arr[index];
                if(args){
                    evFunc(...args);
                }else{
                    evFunc();
                }
            }
        }
    }
    
    static regMouseDown(caller:any, func:Function, args?:any[]){
        this.mouseDownMap ||= [];
        this.mouseDownMap.push(func.bind(caller,...args));
    }

    static regMouseUp(caller:any, func:Function, args?:any[]){
        this.mouseUpMap ||= [];
        this.mouseUpMap.push(func.bind(caller,...args));
    }

    static regMouseMove(caller:any, func:Function, args?:any[]){
        this.mouseMoveMap ||= [];
        this.mouseMoveMap.push(func.bind(caller,...args));
    }

    static regKeyDown(caller:any, func:Function, args?:any[]){
        this.keyDownMap ||= [];
        this.keyDownMap.push(func.bind(caller,...args));
    }

    static regKeyUp(caller:any, func:Function, args?:any[]){
        this.keyUpMap ||= [];
        this.keyUpMap.push(func.bind(caller,...args));
    }
}

enum DocumentEventType{
    MOUSE_DOWN,
    MOUSE_MOVE,
    MOUSE_UP,
    KEY_DOWN,
    KEY_UP
}